# -*- coding: utf-8 -*-
import json

from django.views.decorators.http import require_POST

from common.bankcard import db as bankcard_db
from common.mch import handler as mch_handler
from common.recharge import db as recharge_db
from common.recharge.handler import CHARGE_HANDLE
from common.risk import db as risk_db
from common.utils import exceptions as err
from common.utils import track_logging
from common.utils.api import check_params
from common.utils.decorator import response_wrapper
from common.utils.geo import get_city
from common.utils.respcode import StatusCode

_LOGGER = track_logging.getLogger(__name__)


@require_POST
@response_wrapper
def create(request):
    ''' 下单并获取收款银行卡信息 '''
    params = request.POST.dict()
    _LOGGER.info('create charge: %s' % params)

    check_params(params, [
        'sdk_version', 'mch_id', 'out_trade_no', 'user_id',
        'body', 'total_fee', 'mch_create_ip', 'notify_url',
        'context', 'sign', 'region', 'pay_account_num',
        'pay_account_username', 'pay_account_bank', 'mch_create_ip'
    ],
                 param_type_dct={
                     'mch_id': basestring,
                     'out_trade_no': basestring,
                 }
                 )

    sign = params.pop('sign')
    calculated_sign = mch_handler.generate_sign(params['mch_id'], params)
    if sign != calculated_sign:
        _LOGGER.warning('sign not match, caculated_sign %s, post_sign %s: %s' % \
                        (calculated_sign, sign, params))
        raise err.AuthenticateError('sign error')

    # if float(params['total_fee']) < 48 or float(params['total_fee']) > 1000000:
    if float(params['total_fee']) > 1000000:
        _LOGGER.warning('total_fee not valid: %s' % params['total_fee'])
        raise err.ParamError('total_fee invalid')

    # if params['pay_type'] == 'bankcard' and params['pay_account_num'] == '':
    #     raise err.ParamError('pay_account_num can not be empty')

    params['region'] = get_city(json.loads(params['context'])['user_info'].get('device_ip')) \
                       or params['region']
    params['client_ip'] = json.loads(params['context'])['user_info'].get('device_ip')
    params['register_day'] = json.loads(params['context'])['user_info'].get('account_day')
    sdk_version = params['sdk_version']

    if risk_db.get_risky_card_by_num(params['pay_account_num'], params['mch_id']):
        _LOGGER.error('black card matched: %s' % params)
        raise err.ResourceInsufficient('银行卡卡号错误')

    # 判断out_trade_no是否存在
    exist_order = recharge_db.get_order_by_out_trade_no(
        int(params['mch_id']), params['out_trade_no']
    )
    if exist_order:
        raise err.ParamError('out_trade_no exists')

    user_star, bankcard = bankcard_db.get_bankcard_by_context(params['mch_id'], params['context'], params['pay_type'],
                                                              params['pay_account_num'], sdk_version)
    if not bankcard:
        _LOGGER.error('no bandcard matched: %s' % params)
        raise err.ResourceInsufficient(status=StatusCode.NO_VALID_BANKCARD)

    params['star'] = user_star
    params['receive_card_num'] = bankcard.account_number
    params['receive_card_name'] = bankcard.name
    params['amount'] = float(params['total_fee'])
    params['receive_card_type'] = bankcard.card_type

    order = recharge_db.create_recharge_order(params)

    # 尝试将订单提交到同略云处理
    try:
        CHARGE_HANDLE[bankcard.card_type](order, bankcard)
    except Exception as e:
        _LOGGER.error('recharge order error: %s' % e)

    return {
        "order_id": order.id,
        "bankcard_info": {
            "bank": bankcard.bank,
            "account_number": bankcard.account_number,
            "subbranch": bankcard.subbranch,
            "account_holder": bankcard.account_holder,
        }
    }


@require_POST
@response_wrapper
def query(request):
    ''' 查询上分订单状态 '''
    params = request.POST.dict()
    _LOGGER.info('query order status: %s' % params)
    check_params(params, ['mch_id', 'out_trade_no', 'sign', 'random_num'])

    sign = params.pop('sign')
    calculated_sign = mch_handler.generate_sign(params['mch_id'], params)
    if sign != calculated_sign:
        _LOGGER.warning('sign not match, caculated_sign %s, post_sign %s: %s' % \
                        (calculated_sign, sign, params))
        raise err.AuthenticateError('sign error')

    order = recharge_db.get_order_by_out_trade_no(params['mch_id'], params['out_trade_no'])

    if not order:
        raise err.ParamError('out_trade_no %s not exist' % params['out_trade_no'])
    else:
        receive_card = bankcard_db.get_bankcard_by_num(order.receive_card_num)
        time_remain = recharge_db.get_time_remain(order)
        return {
            "order_id": order.id,
            "order_status": order.status,  # Unionagency 订单状态
            "order_status_summary": recharge_db.trans_order_status(order.status),  # 将Unionagency状态转成商户能理解的状态
            "out_trade_no": params['out_trade_no'],
            "time_remain": time_remain,
            "receive_card_info": {
                "bank": receive_card.bank,
                "account_number": receive_card.account_number,
                "subbranch": receive_card.subbranch,
                "account_holder": receive_card.account_holder,
            },
            "pay_info": {
                "pay_type": order.pay_type,
                "pay_account_num": order.pay_account_num,
                "pay_account_username": order.pay_account_username,
                "amount": order.amount,
            }
        }
